//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension TrustedAdvisor {
    // MARK: Enums

    public enum ExclusionStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case excluded = "excluded"
        case included = "included"
        public var description: String { return self.rawValue }
    }

    public enum RecommendationLanguage: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case bahasaIndonesia = "id"
        case brazilianPortuguese = "pt_BR"
        case chinese = "zh"
        case english = "en"
        case french = "fr"
        case german = "de"
        case italian = "it"
        case japanese = "ja"
        case korean = "ko"
        case spanish = "es"
        case traditionalChinese = "zh_TW"
        public var description: String { return self.rawValue }
    }

    public enum RecommendationLifecycleStage: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case dismissed = "dismissed"
        case inProgress = "in_progress"
        case pendingResponse = "pending_response"
        case resolved = "resolved"
        public var description: String { return self.rawValue }
    }

    public enum RecommendationPillar: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case costOptimizing = "cost_optimizing"
        case faultTolerance = "fault_tolerance"
        case operationalExcellence = "operational_excellence"
        case performance = "performance"
        case security = "security"
        case serviceLimits = "service_limits"
        public var description: String { return self.rawValue }
    }

    public enum RecommendationSource: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case awsConfig = "aws_config"
        case computeOptimizer = "compute_optimizer"
        case costExplorer = "cost_explorer"
        case lse = "lse"
        case manual = "manual"
        case pse = "pse"
        case rds = "rds"
        case resilience = "resilience"
        case resilienceHub = "resilience_hub"
        case securityHub = "security_hub"
        case stir = "stir"
        case taCheck = "ta_check"
        case wellArchitected = "well_architected"
        public var description: String { return self.rawValue }
    }

    public enum RecommendationStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case error = "error"
        case ok = "ok"
        case warning = "warning"
        public var description: String { return self.rawValue }
    }

    public enum RecommendationType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case priority = "priority"
        case standard = "standard"
        public var description: String { return self.rawValue }
    }

    public enum ResourceStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case error = "error"
        case ok = "ok"
        case warning = "warning"
        public var description: String { return self.rawValue }
    }

    public enum UpdateRecommendationLifecycleStage: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case dismissed = "dismissed"
        case inProgress = "in_progress"
        case pendingResponse = "pending_response"
        case resolved = "resolved"
        public var description: String { return self.rawValue }
    }

    public enum UpdateRecommendationLifecycleStageReasonCode: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case lowPriority = "low_priority"
        case nonCriticalAccount = "non_critical_account"
        case notApplicable = "not_applicable"
        case other = "other"
        case otherMethodsAvailable = "other_methods_available"
        case temporaryAccount = "temporary_account"
        case validBusinessCase = "valid_business_case"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AccountRecommendationLifecycleSummary: AWSDecodableShape {
        /// The AWS account ID
        public let accountId: String?
        /// The Recommendation ARN
        public let accountRecommendationArn: String?
        /// When the Recommendation was last updated
        public let lastUpdatedAt: Date?
        /// The lifecycle stage from AWS Trusted Advisor Priority
        public let lifecycleStage: RecommendationLifecycleStage?
        /// The person on whose behalf a Technical Account Manager (TAM) updated the recommendation. This information is only available when a Technical Account Manager takes an action on a recommendation managed by AWS Trusted Advisor Priority
        public let updatedOnBehalfOf: String?
        /// The job title of the person on whose behalf a Technical Account Manager (TAM) updated the recommendation. This information is only available when a Technical Account Manager takes an action on a recommendation managed by AWS Trusted Advisor Priority
        public let updatedOnBehalfOfJobTitle: String?
        /// Reason for the lifecycle stage change
        public let updateReason: String?
        /// Reason code for the lifecycle state change
        public let updateReasonCode: UpdateRecommendationLifecycleStageReasonCode?

        @inlinable
        public init(accountId: String? = nil, accountRecommendationArn: String? = nil, lastUpdatedAt: Date? = nil, lifecycleStage: RecommendationLifecycleStage? = nil, updatedOnBehalfOf: String? = nil, updatedOnBehalfOfJobTitle: String? = nil, updateReason: String? = nil, updateReasonCode: UpdateRecommendationLifecycleStageReasonCode? = nil) {
            self.accountId = accountId
            self.accountRecommendationArn = accountRecommendationArn
            self.lastUpdatedAt = lastUpdatedAt
            self.lifecycleStage = lifecycleStage
            self.updatedOnBehalfOf = updatedOnBehalfOf
            self.updatedOnBehalfOfJobTitle = updatedOnBehalfOfJobTitle
            self.updateReason = updateReason
            self.updateReasonCode = updateReasonCode
        }

        private enum CodingKeys: String, CodingKey {
            case accountId = "accountId"
            case accountRecommendationArn = "accountRecommendationArn"
            case lastUpdatedAt = "lastUpdatedAt"
            case lifecycleStage = "lifecycleStage"
            case updatedOnBehalfOf = "updatedOnBehalfOf"
            case updatedOnBehalfOfJobTitle = "updatedOnBehalfOfJobTitle"
            case updateReason = "updateReason"
            case updateReasonCode = "updateReasonCode"
        }
    }

    public struct BatchUpdateRecommendationResourceExclusionRequest: AWSEncodableShape {
        /// A list of recommendation resource ARNs and exclusion status to update
        public let recommendationResourceExclusions: [RecommendationResourceExclusion]

        @inlinable
        public init(recommendationResourceExclusions: [RecommendationResourceExclusion]) {
            self.recommendationResourceExclusions = recommendationResourceExclusions
        }

        public func validate(name: String) throws {
            try self.recommendationResourceExclusions.forEach {
                try $0.validate(name: "\(name).recommendationResourceExclusions[]")
            }
            try self.validate(self.recommendationResourceExclusions, name: "recommendationResourceExclusions", parent: name, max: 100)
            try self.validate(self.recommendationResourceExclusions, name: "recommendationResourceExclusions", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case recommendationResourceExclusions = "recommendationResourceExclusions"
        }
    }

    public struct BatchUpdateRecommendationResourceExclusionResponse: AWSDecodableShape {
        /// A list of recommendation resource ARNs whose exclusion status failed to update, if any
        public let batchUpdateRecommendationResourceExclusionErrors: [UpdateRecommendationResourceExclusionError]

        @inlinable
        public init(batchUpdateRecommendationResourceExclusionErrors: [UpdateRecommendationResourceExclusionError]) {
            self.batchUpdateRecommendationResourceExclusionErrors = batchUpdateRecommendationResourceExclusionErrors
        }

        private enum CodingKeys: String, CodingKey {
            case batchUpdateRecommendationResourceExclusionErrors = "batchUpdateRecommendationResourceExclusionErrors"
        }
    }

    public struct CheckSummary: AWSDecodableShape {
        /// The ARN of the AWS Trusted Advisor Check
        public let arn: String
        /// The AWS Services that the Check applies to
        public let awsServices: [String]
        /// A description of what the AWS Trusted Advisor Check is monitoring
        public let description: String
        /// The unique identifier of the AWS Trusted Advisor Check
        public let id: String
        /// The column headings for the metadata returned in the resource
        public let metadata: [String: String]
        /// The name of the AWS Trusted Advisor Check
        public let name: String
        /// The Recommendation pillars that the AWS Trusted Advisor Check falls under
        public let pillars: [RecommendationPillar]
        /// The source of the Recommendation
        public let source: RecommendationSource

        @inlinable
        public init(arn: String, awsServices: [String], description: String, id: String, metadata: [String: String], name: String, pillars: [RecommendationPillar], source: RecommendationSource) {
            self.arn = arn
            self.awsServices = awsServices
            self.description = description
            self.id = id
            self.metadata = metadata
            self.name = name
            self.pillars = pillars
            self.source = source
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case awsServices = "awsServices"
            case description = "description"
            case id = "id"
            case metadata = "metadata"
            case name = "name"
            case pillars = "pillars"
            case source = "source"
        }
    }

    public struct GetOrganizationRecommendationRequest: AWSEncodableShape {
        /// The Recommendation identifier
        public let organizationRecommendationIdentifier: String

        @inlinable
        public init(organizationRecommendationIdentifier: String) {
            self.organizationRecommendationIdentifier = organizationRecommendationIdentifier
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.organizationRecommendationIdentifier, key: "organizationRecommendationIdentifier")
        }

        public func validate(name: String) throws {
            try self.validate(self.organizationRecommendationIdentifier, name: "organizationRecommendationIdentifier", parent: name, max: 200)
            try self.validate(self.organizationRecommendationIdentifier, name: "organizationRecommendationIdentifier", parent: name, min: 20)
            try self.validate(self.organizationRecommendationIdentifier, name: "organizationRecommendationIdentifier", parent: name, pattern: "^arn:[\\w-]+:trustedadvisor:::organization-recommendation\\/[\\w-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetOrganizationRecommendationResponse: AWSDecodableShape {
        /// The Recommendation
        public let organizationRecommendation: OrganizationRecommendation?

        @inlinable
        public init(organizationRecommendation: OrganizationRecommendation? = nil) {
            self.organizationRecommendation = organizationRecommendation
        }

        private enum CodingKeys: String, CodingKey {
            case organizationRecommendation = "organizationRecommendation"
        }
    }

    public struct GetRecommendationRequest: AWSEncodableShape {
        /// The Recommendation identifier
        public let recommendationIdentifier: String

        @inlinable
        public init(recommendationIdentifier: String) {
            self.recommendationIdentifier = recommendationIdentifier
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.recommendationIdentifier, key: "recommendationIdentifier")
        }

        public func validate(name: String) throws {
            try self.validate(self.recommendationIdentifier, name: "recommendationIdentifier", parent: name, max: 200)
            try self.validate(self.recommendationIdentifier, name: "recommendationIdentifier", parent: name, min: 20)
            try self.validate(self.recommendationIdentifier, name: "recommendationIdentifier", parent: name, pattern: "^arn:[\\w-]+:trustedadvisor::\\d{12}:recommendation\\/[\\w-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetRecommendationResponse: AWSDecodableShape {
        /// The Recommendation
        public let recommendation: Recommendation?

        @inlinable
        public init(recommendation: Recommendation? = nil) {
            self.recommendation = recommendation
        }

        private enum CodingKeys: String, CodingKey {
            case recommendation = "recommendation"
        }
    }

    public struct ListChecksRequest: AWSEncodableShape {
        /// The aws service associated with the check
        public let awsService: String?
        /// The ISO 639-1 code for the language that you want your checks to appear in.
        public let language: RecommendationLanguage?
        /// The maximum number of results to return per page.
        public let maxResults: Int?
        /// The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.
        public let nextToken: String?
        /// The pillar of the check
        public let pillar: RecommendationPillar?
        /// The source of the check
        public let source: RecommendationSource?

        @inlinable
        public init(awsService: String? = nil, language: RecommendationLanguage? = nil, maxResults: Int? = nil, nextToken: String? = nil, pillar: RecommendationPillar? = nil, source: RecommendationSource? = nil) {
            self.awsService = awsService
            self.language = language
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.pillar = pillar
            self.source = source
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.awsService, key: "awsService")
            request.encodeQuery(self.language, key: "language")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.pillar, key: "pillar")
            request.encodeQuery(self.source, key: "source")
        }

        public func validate(name: String) throws {
            try self.validate(self.awsService, name: "awsService", parent: name, max: 30)
            try self.validate(self.awsService, name: "awsService", parent: name, min: 2)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListChecksResponse: AWSDecodableShape {
        /// The list of Checks
        public let checkSummaries: [CheckSummary]
        /// The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.
        public let nextToken: String?

        @inlinable
        public init(checkSummaries: [CheckSummary], nextToken: String? = nil) {
            self.checkSummaries = checkSummaries
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case checkSummaries = "checkSummaries"
            case nextToken = "nextToken"
        }
    }

    public struct ListOrganizationRecommendationAccountsRequest: AWSEncodableShape {
        /// An account affected by this organization recommendation
        public let affectedAccountId: String?
        /// The maximum number of results to return per page.
        public let maxResults: Int?
        /// The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.
        public let nextToken: String?
        /// The Recommendation identifier
        public let organizationRecommendationIdentifier: String

        @inlinable
        public init(affectedAccountId: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, organizationRecommendationIdentifier: String) {
            self.affectedAccountId = affectedAccountId
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.organizationRecommendationIdentifier = organizationRecommendationIdentifier
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.affectedAccountId, key: "affectedAccountId")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodePath(self.organizationRecommendationIdentifier, key: "organizationRecommendationIdentifier")
        }

        public func validate(name: String) throws {
            try self.validate(self.affectedAccountId, name: "affectedAccountId", parent: name, max: 12)
            try self.validate(self.affectedAccountId, name: "affectedAccountId", parent: name, min: 12)
            try self.validate(self.affectedAccountId, name: "affectedAccountId", parent: name, pattern: "^\\d+$")
            try self.validate(self.organizationRecommendationIdentifier, name: "organizationRecommendationIdentifier", parent: name, max: 200)
            try self.validate(self.organizationRecommendationIdentifier, name: "organizationRecommendationIdentifier", parent: name, min: 20)
            try self.validate(self.organizationRecommendationIdentifier, name: "organizationRecommendationIdentifier", parent: name, pattern: "^arn:[\\w-]+:trustedadvisor:::organization-recommendation\\/[\\w-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListOrganizationRecommendationAccountsResponse: AWSDecodableShape {
        /// The account recommendations lifecycles that are applicable to the Recommendation
        public let accountRecommendationLifecycleSummaries: [AccountRecommendationLifecycleSummary]
        /// The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.
        public let nextToken: String?

        @inlinable
        public init(accountRecommendationLifecycleSummaries: [AccountRecommendationLifecycleSummary], nextToken: String? = nil) {
            self.accountRecommendationLifecycleSummaries = accountRecommendationLifecycleSummaries
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case accountRecommendationLifecycleSummaries = "accountRecommendationLifecycleSummaries"
            case nextToken = "nextToken"
        }
    }

    public struct ListOrganizationRecommendationResourcesRequest: AWSEncodableShape {
        /// An account affected by this organization recommendation
        public let affectedAccountId: String?
        /// The exclusion status of the resource
        public let exclusionStatus: ExclusionStatus?
        /// The maximum number of results to return per page.
        public let maxResults: Int?
        /// The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.
        public let nextToken: String?
        /// The AWS Organization organization's Recommendation identifier
        public let organizationRecommendationIdentifier: String
        /// The AWS Region code of the resource
        public let regionCode: String?
        /// The status of the resource
        public let status: ResourceStatus?

        @inlinable
        public init(affectedAccountId: String? = nil, exclusionStatus: ExclusionStatus? = nil, maxResults: Int? = nil, nextToken: String? = nil, organizationRecommendationIdentifier: String, regionCode: String? = nil, status: ResourceStatus? = nil) {
            self.affectedAccountId = affectedAccountId
            self.exclusionStatus = exclusionStatus
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.organizationRecommendationIdentifier = organizationRecommendationIdentifier
            self.regionCode = regionCode
            self.status = status
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.affectedAccountId, key: "affectedAccountId")
            request.encodeQuery(self.exclusionStatus, key: "exclusionStatus")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodePath(self.organizationRecommendationIdentifier, key: "organizationRecommendationIdentifier")
            request.encodeQuery(self.regionCode, key: "regionCode")
            request.encodeQuery(self.status, key: "status")
        }

        public func validate(name: String) throws {
            try self.validate(self.affectedAccountId, name: "affectedAccountId", parent: name, max: 12)
            try self.validate(self.affectedAccountId, name: "affectedAccountId", parent: name, min: 12)
            try self.validate(self.affectedAccountId, name: "affectedAccountId", parent: name, pattern: "^\\d+$")
            try self.validate(self.organizationRecommendationIdentifier, name: "organizationRecommendationIdentifier", parent: name, max: 200)
            try self.validate(self.organizationRecommendationIdentifier, name: "organizationRecommendationIdentifier", parent: name, min: 20)
            try self.validate(self.organizationRecommendationIdentifier, name: "organizationRecommendationIdentifier", parent: name, pattern: "^arn:[\\w-]+:trustedadvisor:::organization-recommendation\\/[\\w-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListOrganizationRecommendationResourcesResponse: AWSDecodableShape {
        /// The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.
        public let nextToken: String?
        /// A list of Recommendation Resources
        public let organizationRecommendationResourceSummaries: [OrganizationRecommendationResourceSummary]

        @inlinable
        public init(nextToken: String? = nil, organizationRecommendationResourceSummaries: [OrganizationRecommendationResourceSummary]) {
            self.nextToken = nextToken
            self.organizationRecommendationResourceSummaries = organizationRecommendationResourceSummaries
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case organizationRecommendationResourceSummaries = "organizationRecommendationResourceSummaries"
        }
    }

    public struct ListOrganizationRecommendationsRequest: AWSEncodableShape {
        /// After the last update of the Recommendation
        public let afterLastUpdatedAt: Date?
        /// The aws service associated with the Recommendation
        public let awsService: String?
        /// Before the last update of the Recommendation
        public let beforeLastUpdatedAt: Date?
        /// The check identifier of the Recommendation
        public let checkIdentifier: String?
        /// The maximum number of results to return per page.
        public let maxResults: Int?
        /// The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.
        public let nextToken: String?
        /// The pillar of the Recommendation
        public let pillar: RecommendationPillar?
        /// The source of the Recommendation
        public let source: RecommendationSource?
        /// The status of the Recommendation
        public let status: RecommendationStatus?
        /// The type of the Recommendation
        public let type: RecommendationType?

        @inlinable
        public init(afterLastUpdatedAt: Date? = nil, awsService: String? = nil, beforeLastUpdatedAt: Date? = nil, checkIdentifier: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, pillar: RecommendationPillar? = nil, source: RecommendationSource? = nil, status: RecommendationStatus? = nil, type: RecommendationType? = nil) {
            self.afterLastUpdatedAt = afterLastUpdatedAt
            self.awsService = awsService
            self.beforeLastUpdatedAt = beforeLastUpdatedAt
            self.checkIdentifier = checkIdentifier
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.pillar = pillar
            self.source = source
            self.status = status
            self.type = type
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.afterLastUpdatedAt, key: "afterLastUpdatedAt")
            request.encodeQuery(self.awsService, key: "awsService")
            request.encodeQuery(self.beforeLastUpdatedAt, key: "beforeLastUpdatedAt")
            request.encodeQuery(self.checkIdentifier, key: "checkIdentifier")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.pillar, key: "pillar")
            request.encodeQuery(self.source, key: "source")
            request.encodeQuery(self.status, key: "status")
            request.encodeQuery(self.type, key: "type")
        }

        public func validate(name: String) throws {
            try self.validate(self.awsService, name: "awsService", parent: name, max: 30)
            try self.validate(self.awsService, name: "awsService", parent: name, min: 2)
            try self.validate(self.checkIdentifier, name: "checkIdentifier", parent: name, max: 64)
            try self.validate(self.checkIdentifier, name: "checkIdentifier", parent: name, min: 20)
            try self.validate(self.checkIdentifier, name: "checkIdentifier", parent: name, pattern: "^arn:[\\w-]+:trustedadvisor:::check\\/[\\w-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListOrganizationRecommendationsResponse: AWSDecodableShape {
        /// The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.
        public let nextToken: String?
        /// The list of Recommendations
        public let organizationRecommendationSummaries: [OrganizationRecommendationSummary]

        @inlinable
        public init(nextToken: String? = nil, organizationRecommendationSummaries: [OrganizationRecommendationSummary]) {
            self.nextToken = nextToken
            self.organizationRecommendationSummaries = organizationRecommendationSummaries
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case organizationRecommendationSummaries = "organizationRecommendationSummaries"
        }
    }

    public struct ListRecommendationResourcesRequest: AWSEncodableShape {
        /// The exclusion status of the resource
        public let exclusionStatus: ExclusionStatus?
        /// The maximum number of results to return per page.
        public let maxResults: Int?
        /// The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.
        public let nextToken: String?
        /// The Recommendation identifier
        public let recommendationIdentifier: String
        /// The AWS Region code of the resource
        public let regionCode: String?
        /// The status of the resource
        public let status: ResourceStatus?

        @inlinable
        public init(exclusionStatus: ExclusionStatus? = nil, maxResults: Int? = nil, nextToken: String? = nil, recommendationIdentifier: String, regionCode: String? = nil, status: ResourceStatus? = nil) {
            self.exclusionStatus = exclusionStatus
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.recommendationIdentifier = recommendationIdentifier
            self.regionCode = regionCode
            self.status = status
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.exclusionStatus, key: "exclusionStatus")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodePath(self.recommendationIdentifier, key: "recommendationIdentifier")
            request.encodeQuery(self.regionCode, key: "regionCode")
            request.encodeQuery(self.status, key: "status")
        }

        public func validate(name: String) throws {
            try self.validate(self.recommendationIdentifier, name: "recommendationIdentifier", parent: name, max: 200)
            try self.validate(self.recommendationIdentifier, name: "recommendationIdentifier", parent: name, min: 20)
            try self.validate(self.recommendationIdentifier, name: "recommendationIdentifier", parent: name, pattern: "^arn:[\\w-]+:trustedadvisor::\\d{12}:recommendation\\/[\\w-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListRecommendationResourcesResponse: AWSDecodableShape {
        /// The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.
        public let nextToken: String?
        /// A list of Recommendation Resources
        public let recommendationResourceSummaries: [RecommendationResourceSummary]

        @inlinable
        public init(nextToken: String? = nil, recommendationResourceSummaries: [RecommendationResourceSummary]) {
            self.nextToken = nextToken
            self.recommendationResourceSummaries = recommendationResourceSummaries
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case recommendationResourceSummaries = "recommendationResourceSummaries"
        }
    }

    public struct ListRecommendationsRequest: AWSEncodableShape {
        /// After the last update of the Recommendation
        public let afterLastUpdatedAt: Date?
        /// The aws service associated with the Recommendation
        public let awsService: String?
        /// Before the last update of the Recommendation
        public let beforeLastUpdatedAt: Date?
        /// The check identifier of the Recommendation
        public let checkIdentifier: String?
        /// The maximum number of results to return per page.
        public let maxResults: Int?
        /// The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.
        public let nextToken: String?
        /// The pillar of the Recommendation
        public let pillar: RecommendationPillar?
        /// The source of the Recommendation
        public let source: RecommendationSource?
        /// The status of the Recommendation
        public let status: RecommendationStatus?
        /// The type of the Recommendation
        public let type: RecommendationType?

        @inlinable
        public init(afterLastUpdatedAt: Date? = nil, awsService: String? = nil, beforeLastUpdatedAt: Date? = nil, checkIdentifier: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, pillar: RecommendationPillar? = nil, source: RecommendationSource? = nil, status: RecommendationStatus? = nil, type: RecommendationType? = nil) {
            self.afterLastUpdatedAt = afterLastUpdatedAt
            self.awsService = awsService
            self.beforeLastUpdatedAt = beforeLastUpdatedAt
            self.checkIdentifier = checkIdentifier
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.pillar = pillar
            self.source = source
            self.status = status
            self.type = type
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.afterLastUpdatedAt, key: "afterLastUpdatedAt")
            request.encodeQuery(self.awsService, key: "awsService")
            request.encodeQuery(self.beforeLastUpdatedAt, key: "beforeLastUpdatedAt")
            request.encodeQuery(self.checkIdentifier, key: "checkIdentifier")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.pillar, key: "pillar")
            request.encodeQuery(self.source, key: "source")
            request.encodeQuery(self.status, key: "status")
            request.encodeQuery(self.type, key: "type")
        }

        public func validate(name: String) throws {
            try self.validate(self.awsService, name: "awsService", parent: name, max: 30)
            try self.validate(self.awsService, name: "awsService", parent: name, min: 2)
            try self.validate(self.checkIdentifier, name: "checkIdentifier", parent: name, max: 64)
            try self.validate(self.checkIdentifier, name: "checkIdentifier", parent: name, min: 20)
            try self.validate(self.checkIdentifier, name: "checkIdentifier", parent: name, pattern: "^arn:[\\w-]+:trustedadvisor:::check\\/[\\w-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListRecommendationsResponse: AWSDecodableShape {
        /// The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.
        public let nextToken: String?
        /// The list of Recommendations
        public let recommendationSummaries: [RecommendationSummary]

        @inlinable
        public init(nextToken: String? = nil, recommendationSummaries: [RecommendationSummary]) {
            self.nextToken = nextToken
            self.recommendationSummaries = recommendationSummaries
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case recommendationSummaries = "recommendationSummaries"
        }
    }

    public struct OrganizationRecommendation: AWSDecodableShape {
        /// The ARN of the Recommendation
        public let arn: String
        /// The AWS Services that the Recommendation applies to
        public let awsServices: [String]?
        /// The AWS Trusted Advisor Check ARN that relates to the Recommendation
        public let checkArn: String?
        /// When the Recommendation was created, if created by AWS Trusted Advisor Priority
        public let createdAt: Date?
        /// The creator, if created by AWS Trusted Advisor Priority
        public let createdBy: String?
        /// A description for AWS Trusted Advisor recommendations
        public let description: String
        /// The ID which identifies where the Recommendation was produced
        public let id: String
        /// When the Recommendation was last updated
        public let lastUpdatedAt: Date?
        /// The lifecycle stage from AWS Trusted Advisor Priority
        public let lifecycleStage: RecommendationLifecycleStage?
        /// The name of the AWS Trusted Advisor Recommendation
        public let name: String
        /// The Pillars that the Recommendation is optimizing
        public let pillars: [RecommendationPillar]
        /// The pillar aggregations for cost savings
        public let pillarSpecificAggregates: RecommendationPillarSpecificAggregates?
        /// When the Recommendation was resolved
        public let resolvedAt: Date?
        /// An aggregation of all resources
        public let resourcesAggregates: RecommendationResourcesAggregates
        /// The source of the Recommendation
        public let source: RecommendationSource
        /// The status of the Recommendation
        public let status: RecommendationStatus
        /// Whether the Recommendation was automated or generated by AWS Trusted Advisor Priority
        public let type: RecommendationType
        /// The person on whose behalf a Technical Account Manager (TAM) updated the recommendation. This information is only available when a Technical Account Manager takes an action on a recommendation managed by AWS Trusted Advisor Priority
        public let updatedOnBehalfOf: String?
        /// The job title of the person on whose behalf a Technical Account Manager (TAM) updated the recommendation. This information is only available when a Technical Account Manager takes an action on a recommendation managed by AWS Trusted Advisor Priority
        public let updatedOnBehalfOfJobTitle: String?
        /// Reason for the lifecycle stage change
        public let updateReason: String?
        /// Reason code for the lifecycle state change
        public let updateReasonCode: UpdateRecommendationLifecycleStageReasonCode?

        @inlinable
        public init(arn: String, awsServices: [String]? = nil, checkArn: String? = nil, createdAt: Date? = nil, createdBy: String? = nil, description: String, id: String, lastUpdatedAt: Date? = nil, lifecycleStage: RecommendationLifecycleStage? = nil, name: String, pillars: [RecommendationPillar], pillarSpecificAggregates: RecommendationPillarSpecificAggregates? = nil, resolvedAt: Date? = nil, resourcesAggregates: RecommendationResourcesAggregates, source: RecommendationSource, status: RecommendationStatus, type: RecommendationType, updatedOnBehalfOf: String? = nil, updatedOnBehalfOfJobTitle: String? = nil, updateReason: String? = nil, updateReasonCode: UpdateRecommendationLifecycleStageReasonCode? = nil) {
            self.arn = arn
            self.awsServices = awsServices
            self.checkArn = checkArn
            self.createdAt = createdAt
            self.createdBy = createdBy
            self.description = description
            self.id = id
            self.lastUpdatedAt = lastUpdatedAt
            self.lifecycleStage = lifecycleStage
            self.name = name
            self.pillars = pillars
            self.pillarSpecificAggregates = pillarSpecificAggregates
            self.resolvedAt = resolvedAt
            self.resourcesAggregates = resourcesAggregates
            self.source = source
            self.status = status
            self.type = type
            self.updatedOnBehalfOf = updatedOnBehalfOf
            self.updatedOnBehalfOfJobTitle = updatedOnBehalfOfJobTitle
            self.updateReason = updateReason
            self.updateReasonCode = updateReasonCode
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case awsServices = "awsServices"
            case checkArn = "checkArn"
            case createdAt = "createdAt"
            case createdBy = "createdBy"
            case description = "description"
            case id = "id"
            case lastUpdatedAt = "lastUpdatedAt"
            case lifecycleStage = "lifecycleStage"
            case name = "name"
            case pillars = "pillars"
            case pillarSpecificAggregates = "pillarSpecificAggregates"
            case resolvedAt = "resolvedAt"
            case resourcesAggregates = "resourcesAggregates"
            case source = "source"
            case status = "status"
            case type = "type"
            case updatedOnBehalfOf = "updatedOnBehalfOf"
            case updatedOnBehalfOfJobTitle = "updatedOnBehalfOfJobTitle"
            case updateReason = "updateReason"
            case updateReasonCode = "updateReasonCode"
        }
    }

    public struct OrganizationRecommendationResourceSummary: AWSDecodableShape {
        /// The AWS account ID
        public let accountId: String?
        /// The ARN of the Recommendation Resource
        public let arn: String
        /// The AWS resource identifier
        public let awsResourceId: String
        /// The exclusion status of the Recommendation Resource
        public let exclusionStatus: ExclusionStatus?
        /// The ID of the Recommendation Resource
        public let id: String
        /// When the Recommendation Resource was last updated
        public let lastUpdatedAt: Date
        /// Metadata associated with the Recommendation Resource
        public let metadata: [String: String]
        /// The Recommendation ARN
        public let recommendationArn: String
        /// The AWS Region code that the Recommendation Resource is in
        public let regionCode: String
        /// The current status of the Recommendation Resource
        public let status: ResourceStatus

        @inlinable
        public init(accountId: String? = nil, arn: String, awsResourceId: String, exclusionStatus: ExclusionStatus? = nil, id: String, lastUpdatedAt: Date, metadata: [String: String], recommendationArn: String, regionCode: String, status: ResourceStatus) {
            self.accountId = accountId
            self.arn = arn
            self.awsResourceId = awsResourceId
            self.exclusionStatus = exclusionStatus
            self.id = id
            self.lastUpdatedAt = lastUpdatedAt
            self.metadata = metadata
            self.recommendationArn = recommendationArn
            self.regionCode = regionCode
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case accountId = "accountId"
            case arn = "arn"
            case awsResourceId = "awsResourceId"
            case exclusionStatus = "exclusionStatus"
            case id = "id"
            case lastUpdatedAt = "lastUpdatedAt"
            case metadata = "metadata"
            case recommendationArn = "recommendationArn"
            case regionCode = "regionCode"
            case status = "status"
        }
    }

    public struct OrganizationRecommendationSummary: AWSDecodableShape {
        /// The ARN of the Recommendation
        public let arn: String
        /// The AWS Services that the Recommendation applies to
        public let awsServices: [String]?
        /// The AWS Trusted Advisor Check ARN that relates to the Recommendation
        public let checkArn: String?
        /// When the Recommendation was created, if created by AWS Trusted Advisor Priority
        public let createdAt: Date?
        /// The ID which identifies where the Recommendation was produced
        public let id: String
        /// When the Recommendation was last updated
        public let lastUpdatedAt: Date?
        /// The lifecycle stage from AWS Trusted Advisor Priority
        public let lifecycleStage: RecommendationLifecycleStage?
        /// The name of the AWS Trusted Advisor Recommendation
        public let name: String
        /// The Pillars that the Recommendation is optimizing
        public let pillars: [RecommendationPillar]
        /// The pillar aggregations for cost savings
        public let pillarSpecificAggregates: RecommendationPillarSpecificAggregates?
        /// An aggregation of all resources
        public let resourcesAggregates: RecommendationResourcesAggregates
        /// The source of the Recommendation
        public let source: RecommendationSource
        /// The status of the Recommendation
        public let status: RecommendationStatus
        /// Whether the Recommendation was automated or generated by AWS Trusted Advisor Priority
        public let type: RecommendationType

        @inlinable
        public init(arn: String, awsServices: [String]? = nil, checkArn: String? = nil, createdAt: Date? = nil, id: String, lastUpdatedAt: Date? = nil, lifecycleStage: RecommendationLifecycleStage? = nil, name: String, pillars: [RecommendationPillar], pillarSpecificAggregates: RecommendationPillarSpecificAggregates? = nil, resourcesAggregates: RecommendationResourcesAggregates, source: RecommendationSource, status: RecommendationStatus, type: RecommendationType) {
            self.arn = arn
            self.awsServices = awsServices
            self.checkArn = checkArn
            self.createdAt = createdAt
            self.id = id
            self.lastUpdatedAt = lastUpdatedAt
            self.lifecycleStage = lifecycleStage
            self.name = name
            self.pillars = pillars
            self.pillarSpecificAggregates = pillarSpecificAggregates
            self.resourcesAggregates = resourcesAggregates
            self.source = source
            self.status = status
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case awsServices = "awsServices"
            case checkArn = "checkArn"
            case createdAt = "createdAt"
            case id = "id"
            case lastUpdatedAt = "lastUpdatedAt"
            case lifecycleStage = "lifecycleStage"
            case name = "name"
            case pillars = "pillars"
            case pillarSpecificAggregates = "pillarSpecificAggregates"
            case resourcesAggregates = "resourcesAggregates"
            case source = "source"
            case status = "status"
            case type = "type"
        }
    }

    public struct Recommendation: AWSDecodableShape {
        /// The ARN of the Recommendation
        public let arn: String
        /// The AWS Services that the Recommendation applies to
        public let awsServices: [String]?
        /// The AWS Trusted Advisor Check ARN that relates to the Recommendation
        public let checkArn: String?
        /// When the Recommendation was created, if created by AWS Trusted Advisor Priority
        public let createdAt: Date?
        /// The creator, if created by AWS Trusted Advisor Priority
        public let createdBy: String?
        /// A description for AWS Trusted Advisor recommendations
        public let description: String
        /// The ID which identifies where the Recommendation was produced
        public let id: String
        /// When the Recommendation was last updated
        public let lastUpdatedAt: Date?
        /// The lifecycle stage from AWS Trusted Advisor Priority
        public let lifecycleStage: RecommendationLifecycleStage?
        /// The name of the AWS Trusted Advisor Recommendation
        public let name: String
        /// The Pillars that the Recommendation is optimizing
        public let pillars: [RecommendationPillar]
        /// The pillar aggregations for cost savings
        public let pillarSpecificAggregates: RecommendationPillarSpecificAggregates?
        /// When the Recommendation was resolved
        public let resolvedAt: Date?
        /// An aggregation of all resources
        public let resourcesAggregates: RecommendationResourcesAggregates
        /// The source of the Recommendation
        public let source: RecommendationSource
        /// The status of the Recommendation
        public let status: RecommendationStatus
        /// Whether the Recommendation was automated or generated by AWS Trusted Advisor Priority
        public let type: RecommendationType
        /// The person on whose behalf a Technical Account Manager (TAM) updated the recommendation. This information is only available when a Technical Account Manager takes an action on a recommendation managed by AWS Trusted Advisor Priority
        public let updatedOnBehalfOf: String?
        /// The job title of the person on whose behalf a Technical Account Manager (TAM) updated the recommendation. This information is only available when a Technical Account Manager takes an action on a recommendation managed by AWS Trusted Advisor Priority
        public let updatedOnBehalfOfJobTitle: String?
        /// Reason for the lifecycle stage change
        public let updateReason: String?
        /// Reason code for the lifecycle state change
        public let updateReasonCode: UpdateRecommendationLifecycleStageReasonCode?

        @inlinable
        public init(arn: String, awsServices: [String]? = nil, checkArn: String? = nil, createdAt: Date? = nil, createdBy: String? = nil, description: String, id: String, lastUpdatedAt: Date? = nil, lifecycleStage: RecommendationLifecycleStage? = nil, name: String, pillars: [RecommendationPillar], pillarSpecificAggregates: RecommendationPillarSpecificAggregates? = nil, resolvedAt: Date? = nil, resourcesAggregates: RecommendationResourcesAggregates, source: RecommendationSource, status: RecommendationStatus, type: RecommendationType, updatedOnBehalfOf: String? = nil, updatedOnBehalfOfJobTitle: String? = nil, updateReason: String? = nil, updateReasonCode: UpdateRecommendationLifecycleStageReasonCode? = nil) {
            self.arn = arn
            self.awsServices = awsServices
            self.checkArn = checkArn
            self.createdAt = createdAt
            self.createdBy = createdBy
            self.description = description
            self.id = id
            self.lastUpdatedAt = lastUpdatedAt
            self.lifecycleStage = lifecycleStage
            self.name = name
            self.pillars = pillars
            self.pillarSpecificAggregates = pillarSpecificAggregates
            self.resolvedAt = resolvedAt
            self.resourcesAggregates = resourcesAggregates
            self.source = source
            self.status = status
            self.type = type
            self.updatedOnBehalfOf = updatedOnBehalfOf
            self.updatedOnBehalfOfJobTitle = updatedOnBehalfOfJobTitle
            self.updateReason = updateReason
            self.updateReasonCode = updateReasonCode
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case awsServices = "awsServices"
            case checkArn = "checkArn"
            case createdAt = "createdAt"
            case createdBy = "createdBy"
            case description = "description"
            case id = "id"
            case lastUpdatedAt = "lastUpdatedAt"
            case lifecycleStage = "lifecycleStage"
            case name = "name"
            case pillars = "pillars"
            case pillarSpecificAggregates = "pillarSpecificAggregates"
            case resolvedAt = "resolvedAt"
            case resourcesAggregates = "resourcesAggregates"
            case source = "source"
            case status = "status"
            case type = "type"
            case updatedOnBehalfOf = "updatedOnBehalfOf"
            case updatedOnBehalfOfJobTitle = "updatedOnBehalfOfJobTitle"
            case updateReason = "updateReason"
            case updateReasonCode = "updateReasonCode"
        }
    }

    public struct RecommendationCostOptimizingAggregates: AWSDecodableShape {
        /// The estimated monthly savings
        public let estimatedMonthlySavings: Double
        /// The estimated percently monthly savings
        public let estimatedPercentMonthlySavings: Double

        @inlinable
        public init(estimatedMonthlySavings: Double, estimatedPercentMonthlySavings: Double) {
            self.estimatedMonthlySavings = estimatedMonthlySavings
            self.estimatedPercentMonthlySavings = estimatedPercentMonthlySavings
        }

        private enum CodingKeys: String, CodingKey {
            case estimatedMonthlySavings = "estimatedMonthlySavings"
            case estimatedPercentMonthlySavings = "estimatedPercentMonthlySavings"
        }
    }

    public struct RecommendationPillarSpecificAggregates: AWSDecodableShape {
        /// Cost optimizing aggregates
        public let costOptimizing: RecommendationCostOptimizingAggregates?

        @inlinable
        public init(costOptimizing: RecommendationCostOptimizingAggregates? = nil) {
            self.costOptimizing = costOptimizing
        }

        private enum CodingKeys: String, CodingKey {
            case costOptimizing = "costOptimizing"
        }
    }

    public struct RecommendationResourceExclusion: AWSEncodableShape {
        /// The ARN of the Recommendation Resource
        public let arn: String
        /// The exclusion status
        public let isExcluded: Bool

        @inlinable
        public init(arn: String, isExcluded: Bool) {
            self.arn = arn
            self.isExcluded = isExcluded
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 2048)
            try self.validate(self.arn, name: "arn", parent: name, min: 20)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:[\\w-]+:trustedadvisor::\\d{12}:recommendation-resource\\/[\\w-]+\\/[\\w-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case isExcluded = "isExcluded"
        }
    }

    public struct RecommendationResourceSummary: AWSDecodableShape {
        /// The ARN of the Recommendation Resource
        public let arn: String
        /// The AWS resource identifier
        public let awsResourceId: String
        /// The exclusion status of the Recommendation Resource
        public let exclusionStatus: ExclusionStatus?
        /// The ID of the Recommendation Resource
        public let id: String
        /// When the Recommendation Resource was last updated
        public let lastUpdatedAt: Date
        /// Metadata associated with the Recommendation Resource
        public let metadata: [String: String]
        /// The Recommendation ARN
        public let recommendationArn: String
        /// The AWS Region code that the Recommendation Resource is in
        public let regionCode: String
        /// The current status of the Recommendation Resource
        public let status: ResourceStatus

        @inlinable
        public init(arn: String, awsResourceId: String, exclusionStatus: ExclusionStatus? = nil, id: String, lastUpdatedAt: Date, metadata: [String: String], recommendationArn: String, regionCode: String, status: ResourceStatus) {
            self.arn = arn
            self.awsResourceId = awsResourceId
            self.exclusionStatus = exclusionStatus
            self.id = id
            self.lastUpdatedAt = lastUpdatedAt
            self.metadata = metadata
            self.recommendationArn = recommendationArn
            self.regionCode = regionCode
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case awsResourceId = "awsResourceId"
            case exclusionStatus = "exclusionStatus"
            case id = "id"
            case lastUpdatedAt = "lastUpdatedAt"
            case metadata = "metadata"
            case recommendationArn = "recommendationArn"
            case regionCode = "regionCode"
            case status = "status"
        }
    }

    public struct RecommendationResourcesAggregates: AWSDecodableShape {
        /// The number of AWS resources that were flagged to have errors according to the Trusted Advisor check
        public let errorCount: Int64
        /// The number of AWS resources that were flagged to be OK according to the Trusted Advisor check
        public let okCount: Int64
        /// The number of AWS resources that were flagged to have warning according to the Trusted Advisor check
        public let warningCount: Int64

        @inlinable
        public init(errorCount: Int64, okCount: Int64, warningCount: Int64) {
            self.errorCount = errorCount
            self.okCount = okCount
            self.warningCount = warningCount
        }

        private enum CodingKeys: String, CodingKey {
            case errorCount = "errorCount"
            case okCount = "okCount"
            case warningCount = "warningCount"
        }
    }

    public struct RecommendationSummary: AWSDecodableShape {
        /// The ARN of the Recommendation
        public let arn: String
        /// The AWS Services that the Recommendation applies to
        public let awsServices: [String]?
        /// The AWS Trusted Advisor Check ARN that relates to the Recommendation
        public let checkArn: String?
        /// When the Recommendation was created, if created by AWS Trusted Advisor Priority
        public let createdAt: Date?
        /// The ID which identifies where the Recommendation was produced
        public let id: String
        /// When the Recommendation was last updated
        public let lastUpdatedAt: Date?
        /// The lifecycle stage from AWS Trusted Advisor Priority
        public let lifecycleStage: RecommendationLifecycleStage?
        /// The name of the AWS Trusted Advisor Recommendation
        public let name: String
        /// The Pillars that the Recommendation is optimizing
        public let pillars: [RecommendationPillar]
        /// The pillar aggregations for cost savings
        public let pillarSpecificAggregates: RecommendationPillarSpecificAggregates?
        /// An aggregation of all resources
        public let resourcesAggregates: RecommendationResourcesAggregates
        /// The source of the Recommendation
        public let source: RecommendationSource
        /// The status of the Recommendation
        public let status: RecommendationStatus
        /// Whether the Recommendation was automated or generated by AWS Trusted Advisor Priority
        public let type: RecommendationType

        @inlinable
        public init(arn: String, awsServices: [String]? = nil, checkArn: String? = nil, createdAt: Date? = nil, id: String, lastUpdatedAt: Date? = nil, lifecycleStage: RecommendationLifecycleStage? = nil, name: String, pillars: [RecommendationPillar], pillarSpecificAggregates: RecommendationPillarSpecificAggregates? = nil, resourcesAggregates: RecommendationResourcesAggregates, source: RecommendationSource, status: RecommendationStatus, type: RecommendationType) {
            self.arn = arn
            self.awsServices = awsServices
            self.checkArn = checkArn
            self.createdAt = createdAt
            self.id = id
            self.lastUpdatedAt = lastUpdatedAt
            self.lifecycleStage = lifecycleStage
            self.name = name
            self.pillars = pillars
            self.pillarSpecificAggregates = pillarSpecificAggregates
            self.resourcesAggregates = resourcesAggregates
            self.source = source
            self.status = status
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case awsServices = "awsServices"
            case checkArn = "checkArn"
            case createdAt = "createdAt"
            case id = "id"
            case lastUpdatedAt = "lastUpdatedAt"
            case lifecycleStage = "lifecycleStage"
            case name = "name"
            case pillars = "pillars"
            case pillarSpecificAggregates = "pillarSpecificAggregates"
            case resourcesAggregates = "resourcesAggregates"
            case source = "source"
            case status = "status"
            case type = "type"
        }
    }

    public struct UpdateOrganizationRecommendationLifecycleRequest: AWSEncodableShape {
        /// The new lifecycle stage
        public let lifecycleStage: UpdateRecommendationLifecycleStage
        /// The Recommendation identifier for AWS Trusted Advisor Priority recommendations
        public let organizationRecommendationIdentifier: String
        /// Reason for the lifecycle stage change
        public let updateReason: String?
        /// Reason code for the lifecycle state change
        public let updateReasonCode: UpdateRecommendationLifecycleStageReasonCode?

        @inlinable
        public init(lifecycleStage: UpdateRecommendationLifecycleStage, organizationRecommendationIdentifier: String, updateReason: String? = nil, updateReasonCode: UpdateRecommendationLifecycleStageReasonCode? = nil) {
            self.lifecycleStage = lifecycleStage
            self.organizationRecommendationIdentifier = organizationRecommendationIdentifier
            self.updateReason = updateReason
            self.updateReasonCode = updateReasonCode
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.lifecycleStage, forKey: .lifecycleStage)
            request.encodePath(self.organizationRecommendationIdentifier, key: "organizationRecommendationIdentifier")
            try container.encodeIfPresent(self.updateReason, forKey: .updateReason)
            try container.encodeIfPresent(self.updateReasonCode, forKey: .updateReasonCode)
        }

        public func validate(name: String) throws {
            try self.validate(self.organizationRecommendationIdentifier, name: "organizationRecommendationIdentifier", parent: name, max: 200)
            try self.validate(self.organizationRecommendationIdentifier, name: "organizationRecommendationIdentifier", parent: name, min: 20)
            try self.validate(self.organizationRecommendationIdentifier, name: "organizationRecommendationIdentifier", parent: name, pattern: "^arn:[\\w-]+:trustedadvisor:::organization-recommendation\\/[\\w-]+$")
            try self.validate(self.updateReason, name: "updateReason", parent: name, max: 4096)
            try self.validate(self.updateReason, name: "updateReason", parent: name, min: 10)
            try self.validate(self.updateReason, name: "updateReason", parent: name, pattern: "^[\\s\\S]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case lifecycleStage = "lifecycleStage"
            case updateReason = "updateReason"
            case updateReasonCode = "updateReasonCode"
        }
    }

    public struct UpdateRecommendationLifecycleRequest: AWSEncodableShape {
        /// The new lifecycle stage
        public let lifecycleStage: UpdateRecommendationLifecycleStage
        /// The Recommendation identifier for AWS Trusted Advisor Priority recommendations
        public let recommendationIdentifier: String
        /// Reason for the lifecycle stage change
        public let updateReason: String?
        /// Reason code for the lifecycle state change
        public let updateReasonCode: UpdateRecommendationLifecycleStageReasonCode?

        @inlinable
        public init(lifecycleStage: UpdateRecommendationLifecycleStage, recommendationIdentifier: String, updateReason: String? = nil, updateReasonCode: UpdateRecommendationLifecycleStageReasonCode? = nil) {
            self.lifecycleStage = lifecycleStage
            self.recommendationIdentifier = recommendationIdentifier
            self.updateReason = updateReason
            self.updateReasonCode = updateReasonCode
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.lifecycleStage, forKey: .lifecycleStage)
            request.encodePath(self.recommendationIdentifier, key: "recommendationIdentifier")
            try container.encodeIfPresent(self.updateReason, forKey: .updateReason)
            try container.encodeIfPresent(self.updateReasonCode, forKey: .updateReasonCode)
        }

        public func validate(name: String) throws {
            try self.validate(self.recommendationIdentifier, name: "recommendationIdentifier", parent: name, max: 200)
            try self.validate(self.recommendationIdentifier, name: "recommendationIdentifier", parent: name, min: 20)
            try self.validate(self.recommendationIdentifier, name: "recommendationIdentifier", parent: name, pattern: "^arn:[\\w-]+:trustedadvisor::\\d{12}:recommendation\\/[\\w-]+$")
            try self.validate(self.updateReason, name: "updateReason", parent: name, max: 4096)
            try self.validate(self.updateReason, name: "updateReason", parent: name, min: 10)
            try self.validate(self.updateReason, name: "updateReason", parent: name, pattern: "^[\\s\\S]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case lifecycleStage = "lifecycleStage"
            case updateReason = "updateReason"
            case updateReasonCode = "updateReasonCode"
        }
    }

    public struct UpdateRecommendationResourceExclusionError: AWSDecodableShape {
        /// The ARN of the Recommendation Resource
        public let arn: String?
        /// The error code
        public let errorCode: String?
        /// The error message
        public let errorMessage: String?

        @inlinable
        public init(arn: String? = nil, errorCode: String? = nil, errorMessage: String? = nil) {
            self.arn = arn
            self.errorCode = errorCode
            self.errorMessage = errorMessage
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case errorCode = "errorCode"
            case errorMessage = "errorMessage"
        }
    }
}

// MARK: - Errors

/// Error enum for TrustedAdvisor
public struct TrustedAdvisorErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize TrustedAdvisor
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// Exception that access has been denied due to insufficient access
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// Exception that the request was denied due to conflictions in state
    public static var conflictException: Self { .init(.conflictException) }
    /// Exception to notify that an unexpected internal error occurred during processing of the request
    public static var internalServerException: Self { .init(.internalServerException) }
    /// Exception that the requested resource has not been found
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// Exception to notify that requests are being throttled
    public static var throttlingException: Self { .init(.throttlingException) }
    /// Exception that the request failed to satisfy service constraints
    public static var validationException: Self { .init(.validationException) }
}

extension TrustedAdvisorErrorType: Equatable {
    public static func == (lhs: TrustedAdvisorErrorType, rhs: TrustedAdvisorErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension TrustedAdvisorErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
